/*
    Carracci Systems - Carracci Server (openbam project)
    Copyright (C) 2007  Carracci Systems

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.openbam.core.expr;

import org.openbam.core.Event;
import org.openbam.core.TickEvent;


public class Average extends AggregateExpression {

    Double currentValue = new Double(0.0);
    AdditionResizeStrategy ars = new AdditionResizeStrategy();

    public Average() {
        super.setName("Average");
    }

    public Object evaluate(TickEvent event) {
        return null;
    }

    public Object evaluate(Event event) {
//		get the current sum.
        double currentSum = currentValue * operatingWindow.getCurrentWindow().size();
        ars.init();
        //resize the window to it's real size. This is an indicator to OW that a new
        //event has arrived.
        super.operatingWindow.resizeWindow(event, ars);
        Double nestedValue = (Double) super.nestedExpression.evaluate(event);

        nestedValue = nestedValue != null ? nestedValue : 0.0;

        EvaluatedValue evalVal = new EvaluatedValue();
        evalVal.nestedValue = nestedValue;
        evalVal.eventTime = event.getEventTime().getTime();

        //calculate the new average.
        double newSum = currentSum - ars.sum + nestedValue;
        double newAverage = newSum / (operatingWindow.getCurrentWindow().size() + 1);
        evalVal.aggregatedValue = newAverage;

        //set my cuurentValue to the newly computed average.
        currentValue = newAverage;
        operatingWindow.addEvaluatedValue(evalVal);

        return currentValue;
    }

    public Object getValue() {
        return currentValue;
    }

    public IExpression newInstance() {
        Average avg = new Average();
        avg.setNestedExpression(this.nestedExpression.newInstance());
        return avg;
    }
}
